﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DataTier;
using BusinessTier;
using System.Threading.Tasks;
using System.Threading;

namespace GUI
{
    public partial class MainForm : Form
    {
        private ExpenseContainer _expenseContainer = ExpenseContainer.Instance; //Contains two list of expenses (reviewed and not reviewed)
        private ExpenseCtr _expenseCtr = ExpenseCtr.Instance; //Instance of ExpenseController
        private Task _getExpensesTask = null; //Thread to collect data, when opening program
        private SapConnectionCtr sapConnectionCtr = SapConnectionCtr.Instance; //Instance of SapConnectionController
        private EmpCtr _empCtr; //Employee Container
        private Employee _employee;  //Employee 

        private static MainForm instance = null;

        private MainForm()
        {
            InitializeComponent();
        }

        public static MainForm Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new MainForm();
                }
                return instance;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            BuildComboBoxes();
            BuildDataGridView(dataGridAppendix);//Builds datagridview for tab one to show the attributes we want.
            this.WindowState = FormWindowState.Maximized; //Maximize mainform when loaded
            SetUpdateDate();
            EnableGUI(false);
            GetAllExpenses();//Gets the expenses, and show them in the two datagridviews.
            _empCtr = new EmpCtr();
        }


        /// <summary>
        /// Retrieves the expenses from SAP, and shows the results in a datagrid
        /// </summary>
        public void GetAllExpenses()
        {
            if (_getExpensesTask == null)
            {
                _getExpensesTask = new Task(() =>
                    {
                        try
                        {
                            GetExpenses();
                            _getExpensesTask = null;
                            this.Invoke(new Action(() =>
                            {
                                dataGridAppendix.DataSource = null;
                                if (_expenseContainer._expenses.Count > 0)
                                {
                                    dataGridAppendix.DataSource = _expenseContainer._expenses;
                                    ChangeRowColors();
                                    EnableGUI(true);
                                }
                                else
                                {
                                    MessageBox.Show("Der kunne ikke findes nogen expenses ud fra din søgning");
                                    EnableGUI(true);
                                }

                            }));
                        }

                        catch (Exception e)
                        {
                            MessageBox.Show("Der skete en fejl: " + e.Message);
                            EnableGUI(true);
                        }

                    });

                _getExpensesTask.Start();
            }
        }

        /// <summary>
        /// Gets the selected expense from the datagrid. If retrieveall is true, you get all expenses from the chosen employee from the
        /// datagridview. (Only the one which meets the search requirements).
        /// </summary>
        /// <param name="retrieveAll"></param>
        public void ReviewExpenses(bool retrieveAll)
        {
            List<Expense> empExpenseList = new List<Expense>();
            //try
            //{
            Expense expense = (Expense)dataGridAppendix.SelectedRows[0].DataBoundItem;
            if (expense != null && !expense.reviewed.Equals("X"))
            {
                if (retrieveAll)
                {
                    foreach (Expense exp in _expenseContainer._expenses)
                    {
                        if (exp.empID == expense.empID && !exp.reviewed.Equals("X"))
                        {
                            empExpenseList.Add(exp);
                        }
                    }
                }
                else
                {
                    empExpenseList.Add(expense);
                }
                ReviewForm reviewForm = ReviewForm.Instance(empExpenseList);
                reviewForm.Show();
            }
            else
            {
                MessageBox.Show("Denne expense er allerede efterset!");
            }
            //}
            //catch (Exception e)
            //{
            //    MessageBox.Show("Fejl: " + e);
            //}
        }

        /// <summary> 
        /// Gets the expenses which meets the search requirements
        /// </summary>
        private void GetExpenses()
        {
            DateTime startDate = dateTimePickerStart.Value;
            DateTime endDate = dateTimePickerEnd.Value;

            string reviewedString = "Alle";
            string prePaidString = "Alle";
            string paidString = "Alle";

            List<string> types = new List<string>();


            this.Invoke((MethodInvoker)delegate()
        {
            string toAmount = txtToAmount.Text;
            string fromAmount = txtFromAmount.Text;

            if (txtFromAmount.TextLength > 0 && txtToAmount.TextLength <= 0)
            {
                toAmount = int.MaxValue.ToString();
            }

            if (txtToAmount.TextLength > 0 && txtFromAmount.TextLength <= 0)
            {
                fromAmount = int.MinValue.ToString();
            }


            reviewedString = cBoxReviewed.Text;

            if (cBoxReviewed.SelectedItem.ToString().Equals("Efterset"))
            {
                reviewedString = "X";
            }

            if (cBoxReviewed.SelectedItem.ToString().Equals("Ikke efterset"))
            {
                reviewedString = "";
            }

            if (cBoxPrePaid.SelectedItem.ToString().Equals("Forudbetalt"))
            {
                prePaidString = "X";
            }

            if (cBoxPrePaid.SelectedItem.ToString().Equals("Ikke Forudbetalt"))
            {
                prePaidString = "";
            }

            if (cBoxPaid.SelectedItem.ToString().Equals("Betalt"))
            {
                paidString = "X";
            }

            if (cBoxPaid.SelectedItem.ToString().Equals("Ikke Betalt"))
            {
                paidString = "";
            }

            if (_employee == null)
            {
                _employee = new Employee();
                _employee._empNr = "";
            }

            ///Checking types
            if (chckBoxTravel.Checked)
            {
                types.Add("001");
            }
            if (chckBoxAccomodation.Checked)
            {
                types.Add("002");
            }
            if (chckBoxMileage.Checked)
            {
                types.Add("003");
            }
            if (chckBoxDiet.Checked)
            {
                types.Add("004");
            }
            if (chckBoxOther.Checked)
            {
                types.Add("005");
            }

            try
            {
                _expenseCtr.GetAllExpenses(startDate,   //start date
                    endDate,                            //end date            
                    reviewedString,                     //combobox string for reviweed
                    prePaidString,                      //combobox string for prepaid
                    paidString,                         //combobox string for paid
                    toAmount,                           //txtbox toAmount
                    fromAmount,                         //txtbox fromAmount
                    _employee._empNr,                    //Employee from EmployeeForm
                    types);
            }
            catch (Exception e)
            {
                MessageBox.Show("Der er sket en fejl: " + e.Message);
            }
        });

        }

        #region buildgui

        /// <summary>
        /// Builds a new datagridview, so it only shows the information we want, about the expenses.
        /// </summary>
        public void BuildDataGridView(DataGridView dataGridView)
        {
            dataGridView.AutoGenerateColumns = false;

            DataGridViewTextBoxColumn expenseIndicatorColumn = new DataGridViewTextBoxColumn();
            expenseIndicatorColumn.DataPropertyName = "expenseIndicator";
            expenseIndicatorColumn.HeaderText = "Indikator";

            DataGridViewTextBoxColumn appendixColumn = new DataGridViewTextBoxColumn();
            appendixColumn.DataPropertyName = "receiptnr";
            appendixColumn.HeaderText = "Bilag";

            DataGridViewTextBoxColumn posIDColumn = new DataGridViewTextBoxColumn();
            posIDColumn.DataPropertyName = "posID";
            posIDColumn.HeaderText = "WBS nummer";

            DataGridViewTextBoxColumn wbsColumn = new DataGridViewTextBoxColumn();
            wbsColumn.DataPropertyName = "wbs";
            wbsColumn.HeaderText = "WBS beskrivelse";

            DataGridViewTextBoxColumn empIdColumn = new DataGridViewTextBoxColumn();
            empIdColumn.DataPropertyName = "empID";
            empIdColumn.HeaderText = "MA-Nr";

            DataGridViewTextBoxColumn firstNameColumn = new DataGridViewTextBoxColumn();
            firstNameColumn.DataPropertyName = "firstName";
            firstNameColumn.HeaderText = "Fornavn";

            DataGridViewTextBoxColumn lastNameColumn = new DataGridViewTextBoxColumn();
            lastNameColumn.DataPropertyName = "lastName";
            lastNameColumn.HeaderText = "Efternavn";

            DataGridViewTextBoxColumn createDateColumn = new DataGridViewTextBoxColumn();
            createDateColumn.DataPropertyName = "createDate";
            createDateColumn.HeaderText = "Oprettelsesdato";

            DataGridViewTextBoxColumn expenseDateColumn = new DataGridViewTextBoxColumn();
            expenseDateColumn.DataPropertyName = "expenseDate";
            expenseDateColumn.HeaderText = "Udlægsdato";

            DataGridViewTextBoxColumn descriptionColumn = new DataGridViewTextBoxColumn();
            descriptionColumn.DataPropertyName = "description";
            descriptionColumn.HeaderText = "Beskrivelse";

            DataGridViewTextBoxColumn ownTextColumn = new DataGridViewTextBoxColumn();
            ownTextColumn.DataPropertyName = "descr";
            ownTextColumn.HeaderText = "Fritekst";

            DataGridViewTextBoxColumn expenseDescriptionColumn = new DataGridViewTextBoxColumn();
            expenseDescriptionColumn.DataPropertyName = "expenseDescription";
            expenseDescriptionColumn.HeaderText = "Type";

            DataGridViewTextBoxColumn convAmountColumn = new DataGridViewTextBoxColumn();
            convAmountColumn.DataPropertyName = "convAmount";
            convAmountColumn.HeaderText = "Beløb i DKK";

            DataGridViewTextBoxColumn distanceColumn = new DataGridViewTextBoxColumn();
            distanceColumn.DataPropertyName = "distance";
            distanceColumn.HeaderText = "Afstand";

            DataGridViewTextBoxColumn paidColumn = new DataGridViewTextBoxColumn();
            paidColumn.DataPropertyName = "paid";
            paidColumn.HeaderText = "Betalt";

            DataGridViewTextBoxColumn reviewedColumn = new DataGridViewTextBoxColumn();
            reviewedColumn.DataPropertyName = "reviewed";
            reviewedColumn.HeaderText = "Efterset";

            DataGridViewTextBoxColumn prepaidColumn = new DataGridViewTextBoxColumn();
            prepaidColumn.DataPropertyName = "prepaid";
            prepaidColumn.HeaderText = "Forudbetalt";

            DataGridViewTextBoxColumn transferDateColumn = new DataGridViewTextBoxColumn();
            transferDateColumn.DataPropertyName = "transferDate";
            transferDateColumn.HeaderText = "Lønperiode";

            dataGridView.Columns.Add(expenseIndicatorColumn);
            dataGridView.Columns.Add(appendixColumn);
            dataGridView.Columns.Add(posIDColumn);
            dataGridView.Columns.Add(wbsColumn);
            dataGridView.Columns.Add(empIdColumn);
            dataGridView.Columns.Add(firstNameColumn);
            dataGridView.Columns.Add(lastNameColumn);
            dataGridView.Columns.Add(descriptionColumn);
            dataGridView.Columns.Add(createDateColumn);
            dataGridView.Columns.Add(expenseDateColumn);
            dataGridView.Columns.Add(ownTextColumn);
            dataGridView.Columns.Add(expenseDescriptionColumn);
            dataGridView.Columns.Add(convAmountColumn);
            dataGridView.Columns.Add(distanceColumn);
            dataGridView.Columns.Add(paidColumn);
            dataGridView.Columns.Add(reviewedColumn);
            dataGridView.Columns.Add(prepaidColumn);
            dataGridView.Columns.Add(transferDateColumn);
        }

        /// <summary>
        /// Disable the GUI when updating from SAP (enable = false), enables the GUI again when done (enable = true).
        /// </summary>
        /// <param name="enable"></param>
        private void EnableGUI(bool enable)
        {
            if (enable)
            {
                picBoxLoad.Visible = false;
                btnUpdate.Text = "Opdater data";
            }
            else
            {
                picBoxLoad.Visible = true;
                btnUpdate.Text = "Opdaterer tabel";
            }

            txtFromAmount.Enabled = enable;
            txtToAmount.Enabled = enable;
            cBoxPaid.Enabled = enable;
            cBoxPrePaid.Enabled = enable;
            cBoxReviewed.Enabled = enable;
            btnUpdate.Enabled = enable;
            btnReviewAll.Enabled = enable;
            btnReviewOne.Enabled = enable;
            dateTimePickerStart.Enabled = enable;
            dateTimePickerEnd.Enabled = enable;
            btnDeleteEmp.Enabled = enable;
            btnSearchEmp.Enabled = enable;
            chckBoxMileage.Enabled = enable;
            chckBoxOther.Enabled = enable;
            chckBoxAccomodation.Enabled = enable;
            chckBoxDiet.Enabled = enable;
            chckBoxTravel.Enabled = enable;

        }

        /// <summary>
        /// Builds the comboboxes, from where you can choose some search criterias
        /// </summary>
        private void BuildComboBoxes()
        {
            cBoxReviewed.DropDownStyle = ComboBoxStyle.DropDownList;
            cBoxReviewed.Items.Add("Alle");
            cBoxReviewed.Items.Add("Efterset");
            cBoxReviewed.Items.Add("Ikke efterset");
            cBoxReviewed.SelectedItem = "Alle";

            cBoxPrePaid.DropDownStyle = ComboBoxStyle.DropDownList;
            cBoxPrePaid.Items.Add("Alle");
            cBoxPrePaid.Items.Add("Forudbetalt");
            cBoxPrePaid.Items.Add("Ikke Forudbetalt");
            cBoxPrePaid.SelectedItem = "Alle";

            cBoxPaid.DropDownStyle = ComboBoxStyle.DropDownList;
            cBoxPaid.Items.Add("Alle");
            cBoxPaid.Items.Add("Betalt");
            cBoxPaid.Items.Add("Ikke Betalt");
            cBoxPaid.SelectedItem = "Alle";
        }

        /// <summary>
        /// Builds and return the new tooltip
        /// </summary>
        /// <returns></returns>
        private ToolTip BuildToolTip()
        {
            ToolTip toolTip = new ToolTip();
            toolTip.IsBalloon = true;
            toolTip.InitialDelay = 0;
            toolTip.ShowAlways = false;

            return toolTip;
        }

        /// <summary>
        /// Sets the default date of the search to a month ago untill now.
        /// </summary>
        private void SetUpdateDate()
        {
            dateTimePickerStart.Value = DateTime.Today.AddDays(-31);
            dateTimePickerEnd.Value = DateTime.Today;
        }

        /// <summary>
        /// Shows the employee you want the expenses for
        /// </summary>
        /// <param name="e"></param>
        public void showEmployeeInTxt(Employee e)
        {
            txtPerson.Text = e.ToString();
            _employee = e;
        }

        #endregion


        /// <summary>
        /// Change color on rows depending on reviewed or not
        /// </summary>
        /// <param name="e"></param>
        public void ChangeRowColors()
        {
            foreach (DataGridViewRow row in dataGridAppendix.Rows)
            {
                string RowType = row.Cells[15].Value.ToString();

                if (RowType == "X")
                {
                    row.DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#d6d2c2");
                    row.DefaultCellStyle.ForeColor = Color.Black;
                }
                else
                {
                    row.DefaultCellStyle.BackColor = Color.GhostWhite;
                    row.DefaultCellStyle.ForeColor = Color.Black;
                }
            }
        }

        #region eventhandlers

        private void btnReviewOne_Click(object sender, EventArgs e)
        {
            ReviewExpenses(false);
        }

        private void btnReviewAll_Click(object sender, EventArgs e)
        {
            ReviewExpenses(true);
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            EnableGUI(false);
            GetAllExpenses();
        }

        private void txtFromAmount_KeyPress(object sender, KeyPressEventArgs e)
        {
            char ch = e.KeyChar;

            if (!Char.IsDigit(ch) && ch != 8)
            {
                e.Handled = true;
                BuildToolTip().Show("Du skal indtaste et tal", txtFromAmount, 40, -50, 1000);
            }
        }

        private void txtToAmount_KeyPress(object sender, KeyPressEventArgs e)
        {
            char ch = e.KeyChar;

            if (!Char.IsDigit(ch) && ch != 8)
            {
                e.Handled = true;
                BuildToolTip().Show("Du skal indtaste et tal", txtToAmount, 40, -50, 1000);
            }
        }

        private void btnSearchEmp_Click(object sender, EventArgs e)
        {
            EmployeeForm empForm = EmployeeForm.Instance;
            empForm.Show();
        }

        private void DeleteEmp(object sender, EventArgs e)
        {
            txtPerson.Text = "";
            _employee = null;
        }

        #endregion

    }
}